using System.Collections.Generic;

namespace SmartMathLibrary
{
    /// <summary>
    /// Interface to implement a ComplexPolynomial class.
    /// </summary>
    public interface IComplexPolynomial
    {
        /// <summary>
        /// Gets or sets the components of the complex polynomial.
        /// </summary>
        /// <value>The components of the complex polynomial.</value>
        List<ComplexPolynomialComponent> Components { get; }

        /// <summary>
        /// Gets the rank of the polynomial.
        /// </summary>
        /// <value>The rank of the polynomial.</value>
        double Rank { get; }

        /// <summary>
        /// Sets the component at a specified position.
        /// </summary>
        /// <param name="index">The specified position where the value should be set.</param>
        /// <param name="component">The component to set.</param>
        void SetComponentAt(int index, ComplexPolynomialComponent component);

        /// <summary>
        /// Gets a component at a specified position.
        /// </summary>
        /// <param name="index">The specified position from which the component should be returned.</param>
        /// <returns>The component of the polynomial at the specified position.</returns>
        ComplexPolynomialComponent GetComponentAt(int index);

        /// <summary>
        /// Checks if a specified rank exists.
        /// </summary>
        /// <param name="value">The rank to check.</param>
        /// <returns>True if the rank exists in the polynomial otherwise, false.</returns>
        bool ExistRank(double value);

        /// <summary>
        /// Adds a new component to the polynomial at the front of it.
        /// </summary>
        /// <param name="component">The component to add.</param>
        void AddInFrontOf(ComplexPolynomialComponent component);

        /// <summary>
        /// Sorts this polynomial by ranks.
        /// </summary>
        void Sort();

        /// <summary>
        /// Calculates the polynomial with a specified value for x.
        /// </summary>
        /// <param name="x">The specified value for x.</param>
        /// <returns>The result of the polynomial with the specified value for x.</returns>
        ComplexNumber SolveAt(double x);

        /// <summary>
        /// Calculates the polynomial with a specified value for x.
        /// </summary>
        /// <param name="x">The specified value for x.</param>
        /// <returns>The result of the polynomial with the specified value for x.</returns>
        ComplexNumber SolveAt(ComplexNumber x);

        /// <summary>
        /// Creates the first derivative of the polynomial.
        /// </summary>
        /// <returns>Returns the derivative of the polynomial.</returns>
        ComplexPolynomial Derivative();

        /// <summary>
        /// Removes all zero coefficients in the current polynomial.
        /// </summary>
        void RemoveZeroCoefficients();

        /// <summary>
        /// Copies the current instance of the polynomial.
        /// </summary>
        /// <returns>The current instance of the polynomial.</returns>
        ComplexPolynomial Copy();

        /// <summary>
        /// Compares the current instance of a polynomial to another one.
        /// </summary>
        /// <param name="compare">The polynomial to compare.</param>
        /// <returns>True if the polynomials are even otherwise, false.</returns>
        bool CompareTo(ComplexPolynomial compare);

        /// <summary>
        /// Multiplies the polynomial with a scalar.
        /// </summary>
        /// <param name="scalar">The scalar value.</param>
        void MultiplyWithScalar(int scalar);

        /// <summary>
        /// Multiplies the polynomial with a scalar.
        /// </summary>
        /// <param name="scalar">The scalar value.</param>
        void MultiplyWithScalar(double scalar);

        /// <summary>
        /// Multiplies the polynomial with a scalar.
        /// </summary>
        /// <param name="scalar">The scalar value.</param>
        void MultiplyWithScalar(ComplexNumber scalar);

        /// <summary>
        /// Divides the polynomial through a scalar.
        /// </summary>
        /// <param name="scalar">The scalar value.</param>
        void DivideWithScalar(int scalar);

        /// <summary>
        /// Divides the polynomial through a scalar.
        /// </summary>
        /// <param name="scalar">The scalar value.</param>
        void DivideWithScalar(double scalar);

        /// <summary>
        /// Determines whether the polynomial [has only even exponents].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if the polynomial [has only even exponents]; otherwise, <c>false</c>.
        /// </returns>
        bool HasOnlyEvenExponents();

        /// <summary>
        /// Determines whether the polynomial [has only odd exponents].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if the polynomial [has only odd exponents]; otherwise, <c>false</c>.
        /// </returns>
        bool HasOnlyOddExponents();
    }
}